<script setup lang="ts">
import { watch, ref, markRaw, onMounted, onUnmounted, computed } from "vue";
import leftCompWrapper from "../common/leftCompWrapper.vue";
import * as echarts from "echarts";
import { eqpTagLineChart } from "@/api/visual/visualConfig";
import dayjs from "dayjs";
defineOptions({
  name: "VChartLine"
});
const echartRef = ref();
let echartInstance: echarts.ECharts;
const isCollapsed = ref(false);
const nextTimeBtnDisable = computed(() => {
  return judgeTime(dataSelect.value);
});
const props = withDefaults(
  defineProps<{
    propValue?: {
      contentList: Array<any>;
      title?: string;
      collapsed?: boolean;
      iconName?: string;
      option?: Record<string, any>;
    };
    element?: {
      style: {
        width?: number;
        height?: number;
        display?: string;
      };
    };
  }>(),
  {
    propValue: () => ({
      contentList: [],
      option: {},
      title: "",
      collapsed: false,
      iconName: "alert"
    }),
    element: () => ({ style: {} })
  }
);
const dataSelect = ref("");
const switchVal = ref(true);
let option: {
  grid: Record<string, any>;
  legend: Record<string, any>;
  xAxis: Record<string, any>;
  yAxis: Record<string, any>;
  series: any[];
  toolbox: Record<string, any>;
};
let yaxiMap: any[];
let seriesArr: any[];

const selected = ref([]);
watch(
  () => props.propValue.contentList,
  newVal => {
    try {
      if (newVal?.length > 0) {
        selected.value = [newVal[0].tagNum];
      } else {
        selected.value = [];
      }
    } catch (e) {
      console.error(e);
      selected.value = [];
    }

    renderChart(newVal as any);
  },
  { immediate: true }
);

onMounted(() => {
  let [endTime, startTime] = getCurrentTimeAndAdjustedTime();
  dataSelect.value = endTime;
  echartInstance = markRaw(
    echarts.init(echartRef.value, undefined, {
      width: props.element!.style!.width! - 47,
      height: props.element.style.height! - 63
    })
  );
});

//真实渲染数据处理数据
function rednerRealChart() {
  if (echartInstance && echartInstance.resize) {
    echartInstance.resize({
      width: props.element!.style!.width! - 47,
      height: props.element.style.height! - 63
    });

    let emptyOption = {
      title: {
        text: ""
      },
      series: []
    };

    // 配置参数
    echartInstance.clear();
    if (option.series.length > 0) echartInstance.setOption(option, true);
    else echartInstance.setOption(emptyOption, true);
    console.log(option);
  }
}
function dateChange() {
  renderChart(props.propValue.contentList);
}
const disabledDate = (time: Date) => {
  const currentTime = new Date();
  return time.getTime() > currentTime.getTime();
};
function getOneHourBefore(dateTimeStr) {
  const dateTime = dayjs(dateTimeStr, "YYYY-MM-DD HH:mm:ss");
  const oneHourBefore = dateTime.subtract(1, "hour");
  return oneHourBefore.format("YYYY-MM-DD HH:mm:ss");
}
// 新增，解决坐标轴文字太长重叠的问题，兼容value值无空格场景，默认步长为4
function isValidDateTimeFormat(dateTimeString) {
  // 正则表达式匹配 YYYY-MM-DD HH:mm:ss 格式
  const regex = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;

  // 执行匹配
  return regex.test(dateTimeString);
}
function extractTimeFromDateTimeString(dateString) {
  // 正则表达式匹配 YYYY-MM-DD HH:mm:ss 格式
  const regex = /^(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2})$/;
  // 执行匹配
  const match = dateString.match(regex);

  // 如果匹配成功，返回时间部分
  if (match && match[2]) {
    return match[2]; // HH:mm:ss
  }

  // 如果没有匹配成功，返回null或抛出错误
  return dateString;
}
const formatter = (value, step = 4) => {
  if (isValidDateTimeFormat(value)) {
    return extractTimeFromDateTimeString(value);
  } else {
    var words = value.split("");
    var lineWords = [];
    var line = "";
    for (var i = 0; i < words.length; i++) {
      if (line.length + words[i].length <= step) {
        // 每行字符数限制
        line += words[i];
      } else {
        lineWords.push(line);
        line = words[i];
      }
    }
    if (line) {
      lineWords.push(line);
    }
    return lineWords.join("\n");
  }
};
//数据初始化加接口请求
async function renderChart(newVal = []) {
  if (!newVal || newVal.length === 0) return;
  option = deepCopy(props.propValue.option);

  option.toolbox = {
    feature: {
      saveAsImage: {
        title: "导出图片"
      }, // 导出图片
      dataZoom: {
        title: {
          zoom: "放大",
          back: "还原"
        }
      } // 数据区域缩放
    }
  };
  let data = deepCopy(newVal);
  let legendData = deepCopy(selected.value);

  // let tagNums = data.reduce((acc, cur) => {
  //   if (legendData.find(name => cur.title === name)) {
  //     acc.push(cur.tagNum);
  //   }
  //   return acc;
  // }, []);

  let [endTime, startTime] = getCurrentTimeAndAdjustedTime();
  if (dataSelect.value && dataSelect.value !== "") {
    endTime = dataSelect.value;
    startTime = getOneHourBefore(endTime);
  } else {
    dataSelect.value = endTime;
  }

  let rawData = { xaxisList: [], yaxis: [] };
  if (legendData.length > 0) {
    rawData = await eqpTagLineChart({ tagNums: legendData, startTime, endTime });
  } else {
    echartInstance?.clear();
    return;
  }
  let { xaxisList, yaxis } = rawData;
  yaxis = yaxis?.filter(item => !!item.name);
  let selectedYaxis = yaxis.reduce((acc, cur) => {
    if (legendData.find(name => cur.name === name)) {
      acc.push(cur);
    }
    return acc;
  }, []);
  console.log(selectedYaxis);
  try {
    option.grid = {
      // top: "20%",
      // bottom: "20%"
      top: "20%",
      bottom: 0,
      left: "2%",
      right: "5%",
      containLabel: true
    }; // 新增，解决折线图空白区域过多的问题，containLabel:true,宽高包含label
    // option.legend.data = legendData;
    // option.legend.orient = "vertical";
    // option.legend.orient = "0%";
    if (!legendData || legendData.length === 0) return;

    // option.xAxis.data = deepCopy(xaxis);
    delete option.xAxis.data;
    option.xAxis.type = "time";

    option.xAxis.splitNumber = 4;
    // option.xAxis.axisLabel = {
    //   // interval: 13,
    //   formatter: value => formatter(value)
    // };
    yaxiMap = yaxis.map((item, index) => {
      const { name, unit } = item;
      const SPLIT_NUM = 7;
      let max = getMax(Number(Math.max(...yaxis[index].data) || 100), SPLIT_NUM);
      let distance = max / SPLIT_NUM;
      return {
        type: "value",
        name: `${name}(${unit})`,
        show: index > 1 ? false : true,
        position: index === 0 ? "left" : "right",
        max: max,
        min: 0,
        interval: distance,
        splitNumber: SPLIT_NUM,
        nameRotate: index === 0 ? 0.01 : -0.01 // 新增，解决y轴name过长，文字截断显示不全的问题
      };
    });
    option.yAxis = deepCopy(yaxiMap);
    seriesArr = yaxis.map((item, index) => {
      const { name, data } = item;
      let newData = mergeArrays(xaxisList[index], data);

      return {
        name,
        type: "line",
        symbol: "react",
        yAxisIndex: index,
        data: newData,
        connectNulls: true
      };
    });
    option.series = deepCopy(seriesArr);
    rednerRealChart();
    // 更新大小
  } catch (e) {
    console.error(e);
  }
}
async function switchChange(val) {
  if (!val) {
    if (selected.value.length >= 2) {
      selected.value = [selected.value[0]];
      await renderChart(props.propValue.contentList);
    }
  }
}

function getMax(num1, num2) {
  if (!num1 || !num2) {
    return 0;
  }
  num1 = Math.ceil(num1);
  num2 = Math.ceil(num2);

  if (num1 % num2 === 0) {
    return num1;
  }
  for (let i = num1; ; i++) {
    if (i % num2 === 0) {
      return i;
    }
  }
}

function findMinMax(arr) {
  if (arr.length === 0) {
    return { min: null, max: null };
  }

  const min = Math.min(...arr);
  const max = Math.max(...arr);

  return { min, max: Math.ceil(max / 9.5) * 10 };
}
function extractValuesByKey(arr, key) {
  // 检查 arr 是否为数组
  if (!Array.isArray(arr)) {
    return [];
  }

  // 初始化结果数组
  const result = [];

  // 遍历数组对象
  for (const item of arr) {
    // 检查每个元素是否为对象且包含指定的键
    if (item && typeof item === "object" && key in item) {
      result.push(item[key]);
    }
  }

  // 返回结果数组
  return result;
}
function getCurrentTimeAndAdjustedTime(hours = 1) {
  // 获取当前时间
  const now = new Date();

  // 格式化时间为 "YYYY-MM-DD HH:MM:SS"
  function formatDate(date) {
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, "0");
    const day = String(date.getDate()).padStart(2, "0");
    const hours = String(date.getHours()).padStart(2, "0");
    const minutes = String(date.getMinutes()).padStart(2, "0");
    const seconds = String(date.getSeconds()).padStart(2, "0");
    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
  }

  // 当前时间字符串
  const currentTime = formatDate(now);

  // 计算减去指定小时后的时间
  const adjustedTime = new Date(now.getTime() - hours * 60 * 60 * 1000);
  const adjustedTimeString = formatDate(adjustedTime);

  // 返回包含两个时间字符串的数组
  return [currentTime, adjustedTimeString];
}

function deepCopy(data) {
  try {
    return JSON.parse(JSON.stringify(data));
  } catch (error) {
    console.error(error);
    return {};
  }
}
function getAdjustedTime(inputTime) {
  const inputTimeFormatted = dayjs(inputTime).format("YYYY-MM-DD HH:mm:ss");
  const inputTimePlusOneHour = dayjs(inputTimeFormatted).add(1, "hour").format("YYYY-MM-DD HH:mm:ss");
  const currentTimeFormatted = dayjs().format("YYYY-MM-DD HH:mm:ss");
  return dayjs(currentTimeFormatted).isAfter(dayjs(inputTimePlusOneHour)) ? inputTimePlusOneHour : currentTimeFormatted;
}
function judgeTime(inputTime) {
  if (dayjs().isBefore(dayjs(inputTime))) return true;
  if (dayjs().diff(inputTime, "minute") < 1) return true;
  return false;
}

function timeRadioChange(val) {
  if (!dataSelect.value) return;
  if (val === "now") {
    dataSelect.value = dayjs().format("YYYY-MM-DD HH:mm:ss");
    // nextTimeBtnDisable.value = true;
  } else if (val === "pre") {
    dataSelect.value = getOneHourBefore(dataSelect.value);
    // nextTimeBtnDisable.value = false;
  } else {
    dataSelect.value = getAdjustedTime(dataSelect.value);
  }
  dateChange();
}
const toggleDay = async val => {
  if (selected.value.includes(val)) {
    selected.value = selected.value.filter(v => v !== val);
  } else {
    if (switchVal.value) {
      if (selected.value.length >= 2) {
        selected.value.shift();
      }
      selected.value.push(val);
    } else {
      selected.value = [val];
    }
  }
  await renderChart(props.propValue.contentList);
};
function mergeArrays(arr1, arr2) {
  const maxLength = Math.max(arr1.length, arr2.length); // 获取两个数组的最大长度
  const result = [];

  for (let i = 0; i < maxLength; i++) {
    result.push([arr1[i] !== undefined ? arr1[i] : null, arr2[i] !== undefined ? arr2[i] : null]);
  }

  return result;
}
</script>

<template>
  <leftCompWrapper v-model="isCollapsed" :title="propValue.title" :icon-name="propValue.iconName" :has-collapsed="propValue.collapsed">
    <div class="w-[100%] h-[100%] pt-[5px]">
      <px-date-picker
        v-model="dataSelect"
        type="datetime"
        range-separator="至"
        start-placeholder="选择时间"
        :disabled-date="disabledDate"
        value-format="YYYY-MM-DD HH:mm:ss"
        format="YYYY-MM-DD HH:mm:ss"
        @change="dateChange"
      />

      <px-button-group class="mt-[5px] mb-[5px]">
        <px-button type="primary" @click="timeRadioChange('now')">最近一小时</px-button>
        <px-button type="primary" @click="timeRadioChange('pre')">上一小时</px-button>
        <px-button type="primary" :disabled="nextTimeBtnDisable" @click="timeRadioChange('next')">下一小时</px-button>
        <px-switch v-model="switchVal" size="large" active-text="对比" inactive-text="单选" @change="switchChange" />
      </px-button-group>
      <div class="days-select">
        <px-check-tag
          v-for="item in propValue.contentList"
          :key="item.tagNum"
          :checked="selected.includes(item.tagNum)"
          @change="toggleDay(item.tagNum)"
        >
          {{ item.title }}
        </px-check-tag>
      </div>
      <div ref="echartRef" />
    </div>
  </leftCompWrapper>
</template>

<style lang="scss" scoped>
.days-select {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  width: 100%;
  margin-bottom: 15px;
}

.actions {
  display: flex;
  gap: 10px;
}
</style>
